package me.zhengjie.modules.website.service.impl;

import me.zhengjie.modules.website.domain.ColumnTable;
import me.zhengjie.modules.website.repository.ColumnTableRepository;
import me.zhengjie.modules.website.repository.ColumnTableSpecifications;
import me.zhengjie.modules.website.repository.UserColumnRepository;
import me.zhengjie.modules.website.service.ColumnTableService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import me.zhengjie.modules.website.domain.PageResult;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @author system
 * @since 2024-09-26 16:06:29
 */
@Service
public class ColumnTableServiceImpl implements ColumnTableService {

    @Autowired
    private ColumnTableRepository columnTableRepository;

    @Autowired
    private UserColumnRepository userColumnRepository;

    @Override
    public PageResult<ColumnTable> findPage(ColumnTable columnTable, LocalDateTime startDate, LocalDateTime endDate, Pageable pageable) {
        Page<ColumnTable> page = columnTableRepository.findAll((root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();

            // 通过反射遍历 ColumnTable 的所有字段，过滤静态字段
            for (Field field : ColumnTable.class.getDeclaredFields()) {
                field.setAccessible(true); // 允许访问私有字段

                // 跳过静态字段和指定的非持久化字段
                if (Modifier.isStatic(field.getModifiers()) || "secondLevelColumns".equals(field.getName()) || "imgPathList".equals(field.getName())) {
                    continue;
                }

                try {
                    Object value = field.get(columnTable); // 获取字段值
                    if (value != null) { // 如果字段不为空，添加查询条件
                        predicates.add(criteriaBuilder.equal(root.get(field.getName()), value));
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }

            // 时间范围条件，转换 LocalDateTime 为 Timestamp
            if (startDate != null) {
                predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime"), Timestamp.valueOf(startDate)));
            }
            if (endDate != null) {
                predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("createTime"), Timestamp.valueOf(endDate)));
            }

            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        }, pageable);

        PageResult<ColumnTable> result = new PageResult<>();
        result.setContent(page.getContent());
        result.setTotalElements(page.getTotalElements());
        return result;
    }

    @Override
    public List<ColumnTable> findList(ColumnTable columnTable) {
        // 使用 Specifications 创建查询条件
        Specification<ColumnTable> spec = ColumnTableSpecifications.queryList(columnTable);

        // 按 sortOrder 升序排序
        Sort sort = Sort.by(Sort.Direction.ASC, "sortOrder");

        // 返回排序后的结果
        return columnTableRepository.findAll(spec, sort);
    }

    @Override
    public ColumnTable findById(Long id) {
        return columnTableRepository.findById(id).orElse(null);
    }

    @Override
    public ColumnTable insert(ColumnTable columnTable) {
        return columnTableRepository.save(columnTable);
    }

    @Override
    public ColumnTable update(ColumnTable columnTable) {
        return columnTableRepository.saveAndFlush(columnTable);
    }

    @Override
    @Transactional
    public void delete(Long id) {
        userColumnRepository.deleteByColumnId(id);
        columnTableRepository.deleteById(id);
    }

    @Override
    public List<ColumnTable> getAllColumnsWithChildren() {
        // 获取所有一级栏目
        List<ColumnTable> firstLevelColumns = columnTableRepository.findAllFirstLevelColumns();

        // 递归查询所有下级栏目
        for (ColumnTable column : firstLevelColumns) {
            fetchAllChildren(column);  // 递归获取所有子栏目
        }

        return firstLevelColumns;
    }

    private void fetchAllChildren(ColumnTable parentColumn) {
        // 查询当前栏目的子栏目
        List<ColumnTable> children = columnTableRepository.findSecondLevelColumnsNative(parentColumn.getColumnId());

        if (children != null && !children.isEmpty()) {
            // 将子栏目设置为当前栏目的子栏目
            parentColumn.setSecondLevelColumns(children);

            // 递归查询每个子栏目的子栏目
            for (ColumnTable child : children) {
                fetchAllChildren(child);
            }
        }
    }

    @Override
    public List<ColumnTable> findByIds(List<Long> columnIds) {
        return columnTableRepository.findAllById(columnIds);
    }

    @Override
    public List<Long> getAllSubColumnIds(Long columnId) {
        List<Long> columnIds = new ArrayList<>();
        collectSubColumnIds(columnId, columnIds);
        return columnIds;
    }

    private void collectSubColumnIds(Long columnId, List<Long> columnIds) {
        columnIds.add(columnId);
        List<ColumnTable> subColumns = columnTableRepository.findByParentColumnId(columnId);
        for (ColumnTable subColumn : subColumns) {
            collectSubColumnIds(subColumn.getColumnId(), columnIds);
        }
    }

}
